home *** CD-ROM | disk | FTP | other *** search
-
- A Pixel-Precision Method For Detecting Sprite Collision
-
- v 1.0
-
- by Mark Mackey
-
-
- ---
-
- Introduction
-
- ----
-
-
- A common query on the USENET newsgroup rec.games.programmer over the
-
- years has been how to do fast pixel-precision collision detection. A
-
- number of people have presented some excellent algorithms for extending
-
- and speeding up bounding-box collision detection between large numbers of
-
- objects (for instance, dividing the play area into subfields and sorting
-
- the sprites into these subfields, thus greatly reducing the number of
-
- sprite-sprite collisions that have to be checked in the first place).
-
-
- However, there have been little information available on how to detect
-
- collisions efficiently at the pixel level. I thus present here some code
-
- from my game XQuest (blatant plug) which checks for collisions at the
-
- pixel level. The routine assumes that the bounding boxes for the two
-
- sprites overlap, and hence should be relatively easy to add to an
-
- existing bounding-box collision detection routine. This code is fast,
-
- relatively efficient in terms of space (requiring 4 bytes per row of each
-
- sprite), and even works! The one limitation is that sprites are assumed
-
- to be 32 pixels or less in width. For larger sprites, you could either
-
- treat them as 2 or more 32-pixel wide objects, or with a bit of creative
-
- thought this routine could be rewritten to allow for 64-pixel wide
-
- objects on the 386 (left as an exercise for the reader :).
-
-
- The code in the enclosed file COLLIDE.PAS is organised as a Turbo Pascal
-
- unit, but all of the essential code is in assembly language and could be
-
- easily ported to work under C or in a pure asm program. If any of the
-
- Pascalisations confuse you just let me know and I'll explain :). Also, if
-
- you need a version of this code to work on a 286 then let me know and
-
- I'll send it to you (but be warned: it's not nearly as nice :).
-
-
- ---
-
- The Algorithm
-
- ---
-
-
- The first step is to create a 'transparency' mask for each sprite. The
-
- mask consists of a dword for each row of the sprite, with each bit being
-
- a 0 if the corresponding pixel is 'empty', and a 1 otherwise. For
-
- example, if a row of your sprite looked like (colour indexes, 0 being
-
- transparent)
-
-
- 0 0 0 1 23 42 0 1 56 0 0 0 0 0
-
-
- the the corresponging mask bytes would be
-
-
- 00011101 10000000 00000000 00000000 = 1D 80 00 00
-
-
- The MakeMask procedure given will produce such a mask from a sprite
-
- supplied in the XLib linear bitmap format (with pixels of colour zero
-
- being transparent), and is easily adaptable to your own sprite format.
-
-
- OK, now the hard part. We have found in our general-purpose bounding-box
-
- collision detection routine that two sprites' bounding boxes have
-
- collided (ie their masks overlap).
-
-
- Let the leftmost sprite have (x1,y1) as the coords of its top left
-
- corner, and the rightmost one (x2,y2). Take the mask entry for row
-
- |y2-y1| of the topmost sprite and shift it left by the difference in the
-
- x-coordinates (x2-x1). AND this value with the 1st mask entry of the
-
- lower sprite. If the result is non-zero then a collision occurred on this
-
- row. If not, then shift row |y2-y1+1| and compare it to row 2 of the
-
- lower sprite, and so on, until you reach the bottom of one of the
-
- sprites. If no collision has been detected by this time, then the sprites
-
- didn't collide. Simple, eh?
-
-
- This routine is quite fast, requiring only a MOV, a SHL and an AND for
-
- each row checked, and only checking those rows that overlap.
-
-
- ---
-
- The Legal Bit
-
- ---
-
-
- This software is (C) Copyright 1995 Mark Mackey. Permission is given to
-
- distribute this code freely, or to distribute modified forms of this
-
- software provided that the author is acknowledged and this copyright
-
- notice retained. Permission is also given to utilise this code in
-
- original or modified form in any software provided that the author is
-
- acknowledged.
-
-
- I can be contacted by
-
-
- Email: mdm1004@cus.cam.ac.uk
-
- WWW: http://www.ch.cam.ac.uk/MMRG/mdm.html
-
- Snail: c/o Trinity Hall,
-
- Cambridge CB2 1TJ
-
- UK
-
-
- These addresses will be in use until at least October 1996. Please let me
-
- know if you found this code helpful/useful/rubbish/whatever or if you
-
- improve it :)
-
-
-